package com.lihaozhe.util.localdatetime;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * @author 李昊哲
 * @Description
 * @createTime 2021/7/14 上午10:56
 */
public abstract class BaseLocalDateTime {
    /**
     * 时间格式化模板字符串
     */
    private static final String formatter = "yyyy-MM-dd HH:mm:ss";
    /**
     * 默认时区为东8区
     */
    private static final ZoneOffset zoneOffset = ZoneOffset.of("+8");

    /**
     * 将LocalDateTime格式化为时间指定的时间格式字符串
     *
     * @param dateTime 欲被格式化的时间
     * @return 根据时间格式字符串模板格式化的时间字符串
     */
    public static String format(LocalDateTime dateTime) {
        return DateTimeFormatter.ofPattern(formatter).format(dateTime);
    }

    /**
     * 将LocalDateTime格式化为时间指定的时间格式字符串
     *
     * @param dateTime  欲被格式化的时间
     * @param formatter 时间字符串模板
     * @return 根据时间格式字符串模板格式化的时间字符串
     */
    public static String format(LocalDateTime dateTime, String formatter) {
        return DateTimeFormatter.ofPattern(formatter).format(dateTime);
    }

    /**
     * 根据时间字符串模板将时间格式字符串解析为LocalDateTime
     *
     * @param text 时间字符串
     * @return
     */
    public static LocalDateTime parse(String text) {
        return LocalDateTime.parse(text, DateTimeFormatter.ofPattern(formatter));
    }

    /**
     * 根据时间字符串模板将时间格式字符串解析为LocalDateTime
     *
     * @param text      时间字符串
     * @param formatter 时间字符串模板
     * @return
     */
    public static LocalDateTime parse(String text, String formatter) {
        return LocalDateTime.parse(text, DateTimeFormatter.ofPattern(formatter));
    }

    /**
     * LocalDateTime类型的时间转为Date类型的时间
     *
     * @param dateTime LocalDateTime
     * @return Date
     */
    public static Date toDate(LocalDateTime dateTime) {
        return Date.from(dateTime.toInstant(zoneOffset));
    }

    /**
     * LocalDateTime类型的时间转为Date类型的时间
     *
     * @param dateTime   LocalDateTime
     * @param zoneOffset 时区
     * @return DateLocalDateTime
     */
    public static Date toDate(LocalDateTime dateTime, ZoneOffset zoneOffset) {
        return Date.from(dateTime.toInstant(zoneOffset));
    }


    /**
     * Date类型的时间转为LocalDateTime类型的时间
     *
     * @param date Date
     * @return Date
     */
    public static LocalDateTime fromDate(Date date) {
        return date.toInstant().atOffset(zoneOffset).toLocalDateTime();
    }

    /**
     * Date类型的时间转为LocalDateTime类型的时间
     *
     * @param date       Date
     * @param zoneOffset 时区
     * @return Date
     */
    public static LocalDateTime fromDate(Date date, ZoneOffset zoneOffset) {
        return date.toInstant().atOffset(zoneOffset).toLocalDateTime();
    }

    public static String nowString() {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatter);
        LocalDateTime now = LocalDateTime.now(zoneOffset);
        return dateTimeFormatter.format(now);
    }

    public static String nowString(String formatter) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatter);
        LocalDateTime now = LocalDateTime.now(zoneOffset);
        return dateTimeFormatter.format(now);
    }

    public static String nowString(ZoneOffset zoneOffset) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatter);
        LocalDateTime now = LocalDateTime.now(zoneOffset);
        return dateTimeFormatter.format(now);
    }

    public static String nowString(ZoneOffset zoneOffset, String pattern) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        LocalDateTime now = LocalDateTime.now(zoneOffset);
        return formatter.format(now);
    }
    /**
     * 生成size数量的随机时间，位于[start,end)范围内 时间倒序排列
     *
     * @param start 开始时间
     * @param end   结束时间
     * @param size  生成时间个数
     * @return List<LocalDateTime>
     * @throws Exception
     */
    public static List<LocalDateTime> randomDateTime(String start, String end, int size) throws Exception {
        return randomDateTime(parse(start), parse(end), size);
    }

    /**
     * 生成size数量的随机时间，位于[start,end)范围内 时间倒序排列
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param size      生成时间个数
     * @return List<LocalDateTime>
     * @throws Exception
     */
    public static List<LocalDateTime> randomDateTime(LocalDateTime startTime, LocalDateTime endTime, int size) throws Exception {
        long startMilli = startTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long endMilli = endTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        List<LocalDateTime> dates = ThreadLocalRandom.current().longs(size, startMilli,endMilli).mapToObj(t -> LocalDateTime.ofEpochSecond(t / 1000, 0, ZoneOffset.ofHours(8))).collect(Collectors.toList());
        dates.sort((t1, t2) -> {
            return t1.compareTo(t2);
        });
        return dates;
    }
}
